#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    recive_num =0;
    isPortOpen = false;
    isSendhex =false;
    isUpdatePortInfo = false;
    transmit_total =0;



     //界面初始化
    btn_settingGroup = new QButtonGroup(this);
    btn_settingGroup->addButton(ui->cbx_HexRec);
    btn_settingGroup->addButton(ui->cbx_Night);
    btn_settingGroup->addButton(ui->cbx_DTR);
    btn_settingGroup->addButton(ui->cbx_RTS);
    btn_settingGroup->addButton(ui->cbx_TimeStamp);
    btn_settingGroup->setExclusive(false);
    connect(btn_settingGroup,SIGNAL(buttonToggled(QAbstractButton*,bool)),this,SLOT(on_settingGroup(QAbstractButton*,bool)));


    ui->edit_Rec->setReadOnly(true);
    ui->edit_RecHex->setReadOnly(true);
    ui->edit_Rec->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    ui->edit_RecHex->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

    ui->stackedWidget->setCurrentIndex(0);

    QMenu *toolMenu = new QMenu(this);
    QAction *action_cal =new QAction("计算器",this);
    QAction *action_parity =new QAction("校验计算",this);
    toolMenu->addAction(action_cal);
    toolMenu->addAction(action_parity);
    ui->tbn_Tool->setPopupMode(QToolButton::InstantPopup);
    ui->tbn_Tool->setMenu(toolMenu);

    connect(action_cal,SIGNAL(triggered(bool)),this,SLOT(on_cal(bool)));
    /*TODO  完成工具箱的功能   */

    ui->Spx_AlignBytes->setValue(100);
    alignLen = ui->Spx_AlignBytes->value();

    QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
    foreach (QSerialPortInfo info, infos) {
        ports_str.append(info.portName()+":"+info.description());
   }

    ports_str.sort();
     ui->cbb_PortName->addItems(ports_str);

     //波特率选项
    QStringList baud = {"2400","4800","9600","19200","38400","56700",\
                        "115200", "128000","256000","921600"};
    ui->cbb_BaudRate->addItems(baud);
    ui->cbb_BaudRate->setCurrentIndex(6);

    //停止位选项
    ui->cbb_StopBits->addItem("1");
    ui->cbb_StopBits->addItem("1.5");
    ui->cbb_StopBits->addItem("2");

    //数据为选项
    ui->cbb_DataBits->addItem("8");
    ui->cbb_DataBits->addItem("7");
    ui->cbb_DataBits->addItem("6");
    ui->cbb_DataBits->addItem("5");

    //校验位选项
    ui->cbb_ParityBit->addItem("无");
    ui->cbb_ParityBit->addItem("奇校验");
    ui->cbb_ParityBit->addItem("偶校验");

    //用定时器监测串口插拔情况，更新串口设备显示
    timer1  = new QTimer(this);
    connect(timer1,SIGNAL(timeout()),this,SLOT(on_timer1()));
    timer1->start(1000);

    ui->btn_OpenPort->setText("打开串口");



    qDebug()<<"主线程ThreadID:"<<QThread::currentThreadId();
    testObj = new SerialManager();

    connect(testObj,SIGNAL(update_data(QByteArray, QByteArray )),this,SLOT(display_data(QByteArray, QByteArray)));
    connect(testObj,SIGNAL(error(int,QString)),this,SLOT(onError(int,QString)));

    testObj->moveToThread(&thread);
    thread.start();


}

//轮查串口状态
void Widget::on_timer1()
{
    QStringList ports;
    QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
    foreach (QSerialPortInfo info, infos) {
        ports.append(info.portName()+":"+info.description());
   }

    ports.sort();


    if(ports != ports_str)
    {
        //更新串口信息显示过程中不切换打开的串口

        isUpdatePortInfo = true;

        ui->cbb_PortName->clear();
        ui->cbb_PortName->addItems(ports);
        ui->cbb_PortName->update();

        //如果已经有串口打开,则选中已经打开的串口
        if(isPortOpen)
        {
            int index = ui->cbb_PortName->findText(current_portName,Qt::MatchContains);

            if(index<0)
            {
                //打开的串口已经被拔出
                testObj->closePort();
                ui->btn_OpenPort->setText("打开串口");
                isPortOpen = false;
                qDebug()<<"当前串口被移除";
                current_portName.clear();
            }
            else
            {
                ui->cbb_PortName->setCurrentIndex(index);
            }
        }

        ports_str = ports;
        isUpdatePortInfo = false;
    }
    //显示系统时间
    ui->label_time->setText("Now:"+QTime::currentTime().toString());
}
Widget::~Widget()
{
    thread.quit();
    thread.wait();
    delete ui;
}

//串口打开与关闭
void Widget::on_btn_OpenPort_clicked()
{
    if(isPortOpen)
    {
        testObj->closePort();
        ui->btn_OpenPort->setText("打开串口");
        isPortOpen = false;
        current_portName.clear();
    }
    else
    {
        current_portName = ui->cbb_PortName->currentText();
        QString portName = current_portName.split(':').at(0);

         testObj->openPort(portName);
         isPortOpen=true;
         ui->btn_OpenPort->setText("关闭串口");

         //设置串口参数
         this->on_cbb_BaudRate_currentTextChanged(ui->cbb_BaudRate->currentText());
         this->on_cbb_StopBits_currentIndexChanged(ui->cbb_StopBits->currentIndex());
         this->on_cbb_DataBits_currentTextChanged(ui->cbb_DataBits->currentText());
         this->on_cbb_ParityBit_currentIndexChanged(ui->cbb_ParityBit->currentIndex());

    }
}

void Widget::display_data(QByteArray data_hex,QByteArray data_str)
{

//    //滚动条不在底部时，保持当前滚动条的位置，以让显示的内容不变
//    int scroll_value=ui->textEdit->verticalScrollBar()->value();
//    int scroll_maxnum=ui->textEdit->verticalScrollBar()->maximum();
//    bool atbottom =( scroll_value== scroll_maxnum);

    //转换成ascii字符串


    QString data_temp = QString::fromLocal8Bit(data_str);
    //转换成Hex字符串
   // QString temp_str1 = HexConvertor::HextoHexString(data,alignLen);


    ui->edit_Rec->moveCursor(QTextCursor::End);
    ui->edit_Rec->insertPlainText(data_temp);
    ui->edit_Rec->moveCursor(QTextCursor::End);

    data_temp = QString::fromLocal8Bit(data_hex);
     ui->edit_RecHex->moveCursor(QTextCursor::End);
     ui->edit_RecHex->insertPlainText(data_temp);
     ui->edit_RecHex->moveCursor(QTextCursor::End);

     quint64 rec_total = testObj->getRecCount();
     ui->label_recNum->setText( QString("R:%1").arg(rec_total));



    //设置滚动条位置
//   if(!atbottom )
//       ui->textEdit->verticalScrollBar()->setValue(scroll_value);
//   else
//   {
//       scroll_maxnum=ui->textEdit->verticalScrollBar()->maximum();
//       ui->textEdit->verticalScrollBar()->setValue(scroll_maxnum);
//   }


}

//错误提示
void Widget::onError(int error,QString msg)
{
    if(error == 1) //串口打开失败
    {
        isPortOpen=false;
        ui->btn_OpenPort->setText("打开串口");
    }
    QToolTip::showText(ui->btn_OpenPort->mapToGlobal(QPoint(0,5)),msg);

}

//更改串口号
void Widget::on_cbb_PortName_currentTextChanged(const QString &arg1)
{
    if(isPortOpen &&  !isUpdatePortInfo)
    {
        QString portName=arg1.split(':').at(0);
        testObj->openPort(portName);

        current_portName = arg1;
        qDebug()<<"串口号改为:"<<current_portName;
    }
}

//清除接收
void Widget::on_btn_ClearRec_clicked()
{
    ui->edit_Rec->clear();
    ui->edit_RecHex->clear();
    testObj->setAlignment(alignLen);
    testObj->clearData();
    ui->label_recNum->setText("R:0");

    transmit_total =0;
    ui->label_transmit->setText("S:0");
}

//发送数据
void Widget::on_btn_Send_clicked()
{

    QString text = ui->edit_Transmit->toPlainText();


    if(isPortOpen)
    {
        QByteArray dat;
        if(isSendhex)
        {
             dat =HexConvertor::hexStringtoHex(text);
             transmit_total+=dat.size();
        }
        else
        {
            dat = text.toLocal8Bit();
            transmit_total+=dat.size();
        }

        testObj->sendData(dat);
        ui->label_transmit->setText(QString("S:%1").arg(transmit_total));
    }
}




//发送方式设置
void Widget::on_cbx_HexTransmit_toggled(bool checked)
{
    if(checked)
    {
        //16进制发送
       isSendhex =true;
       ui->edit_Transmit->setAttribute(Qt::WA_InputMethodEnabled,false);

       ui->edit_Transmit->installEventFilter(&pressHander);
       ui->edit_Transmit->setHex(true);

       //TODO 把当前内容转换成16进制字符串
       QByteArray dataArray = ui->edit_Transmit->toPlainText().toLocal8Bit();

       qDebug()<<dataArray;
        QString str_temp = HexConvertor::hextoHexString( dataArray);
        ui->edit_Transmit->setPlainText(str_temp);

    }
    else
    {
        //GBK发送
        isSendhex =false;
        ui->edit_Transmit->setAttribute(Qt::WA_InputMethodEnabled,true);
        ui->edit_Transmit->removeEventFilter(&pressHander);
        ui->edit_Transmit->setHex(false);

        //TODO 把当前内容转换成 ascii

        QString data_str = ui->edit_Transmit->toPlainText();
        QByteArray data_hex = HexConvertor::hexStringtoHex(data_str);


        //删除16进制数据中的，字符串中间不允许有0出现
        int zeroIndex = data_hex.indexOf('\0');
        while(zeroIndex>=0)
        {
            data_hex.remove(zeroIndex,1);
            zeroIndex = data_hex.indexOf('\0',zeroIndex);
        }


        data_str = QString::fromLocal8Bit(data_hex);

        ui->edit_Transmit->setPlainText(data_str);
    }
}


//接收显示设置
void Widget::on_settingGroup(QAbstractButton* btn,bool checked)
{
    if(btn == ui->cbx_HexRec)
    {
        if(checked)
        {
            //qDebug()<<"16进制显示";
            ui->stackedWidget->setCurrentIndex(1);
        }
        else
        {
          //  qDebug()<<"ascii显示";
            ui->stackedWidget->setCurrentIndex(0);
        }
    }
    else if(btn == ui->cbx_TimeStamp)
    {
        testObj->setTimeStamp(checked);
    }
}


//对齐字节数发生改变
void Widget::on_Spx_AlignBytes_editingFinished()
{
   uint len = ui->Spx_AlignBytes->value();
   if(alignLen != len)
   {
        testObj->setAlignment( ui->Spx_AlignBytes->value());
        alignLen = len;
   }
}

//波特率变化
void Widget::on_cbb_BaudRate_currentTextChanged(const QString &baud)
{
    if(isPortOpen)
    {
        testObj->setPortBaudRate(baud);
    }
}

//停止位变化
void Widget::on_cbb_StopBits_currentIndexChanged(int index)
{
    QSerialPort::StopBits stopBits ;
    if(isPortOpen)
    {
        switch (index) {
        case 0:
            stopBits = QSerialPort::OneStop;
            break;
        case 1:
            stopBits = QSerialPort::OneAndHalfStop;
            break;
        case 2:
            stopBits = QSerialPort::TwoStop;
            break;
        default:
            stopBits = QSerialPort::UnknownStopBits;
            break;
        }
        testObj->setPortStopBits(stopBits);
    }
}

//数据位变化
void Widget::on_cbb_DataBits_currentTextChanged(const QString &arg1)
{
    QSerialPort::DataBits dataBits;
    if(isPortOpen)
    {
        dataBits = QSerialPort::DataBits(arg1.toInt());
        testObj->setPortDataBits(dataBits);
    }

}

//校验位发生变化
void Widget::on_cbb_ParityBit_currentIndexChanged(int index)
{
    QSerialPort::Parity parity ;
    if(isPortOpen)
    {
        switch (index) {
        case 0:
            parity = QSerialPort::NoParity;
            break;
        case 1:
            parity = QSerialPort::OddParity;
            break;
        case 2:
            parity = QSerialPort::EvenParity;
            break;
        default:
            parity = QSerialPort::UnknownParity;
            break;
        }
        testObj->setPortParity(parity);
    }
}

//清除发送数据
void Widget::on_btn_ClearTransmit_clicked()
{
    ui->edit_Transmit->clear();
    transmit_total =0;
    ui->label_transmit->setText("S:0");
}

void Widget::on_cal(bool /*cmd*/)
{
    QProcess::execute("C:/windows/system32/calc.exe");
}
